/*
 *  Librarie de tipuri de date abstracte (TDA)
 
    Copyright (C) 2007  Catedra de Structuri de Date

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/**
@file linkedstack.h
@author Mihai Balan
@brief This header file contains the structures and functions needed to work
with stacks (implemented using doubly-linked lists)

It contains functions for creating a stack, destroying it and all the typical
operations on a stack (push, pop, top).
*/

#ifndef LINKEDSTACK_H_
#define LINKEDSTACK_H_

struct linkedstack_adt;

/**
@brief Pointer to structure representing a stack.

The \c LinkedStack is implemented using a \c LinkedList . However, the underlying \c LinkedList should not be modified directly but only through the
appropriate functions.

As is the case with the \c LinkedList element data is stored using a \c void*
pointer. Thus, one should note there is no way to tell what kind of data is
stored in the list or in a particular element.

@see LS_New(), LS_Free(), LS_Pop(), LS_Push(), LS_Top()
*/
typedef struct linkedstack_adt* LinkedStack;

/**
@brief Creates a new stack.

The function creates a new linked stack (stack implemented using a
\c LinkedList ).

@return pointer to the newly created stack.
*/
LinkedStack LS_New();

/**
@brief Destroys the specified stack.

The function freees the memory used by the stack structure itself as well as the
memory used by the data in the stack, so trying to access the data after the
destruction of the stack (e.g. through a pointer) will most likely result in a
Access Violation / segfault.

@param stack \c LinkedStack representing the stack to be destroyed.
*/
void LS_Free(LinkedStack stack);

/**
@brief Returns the size of the stack.

The function returns the number of elements in the stack.

@param stack stack to be tested
@return number of elements in the stack.
*/
int LS_Size(LinkedStack stack);

/**
@brief Determines if the stack is empty or not.

The function actually returns the value of the expression <tt>Size==0</tt>.

@param stack the stack to be tested.
@return \c -1 if \a stack is \c NULL, \c 1 if the stack is empty,
\c 0 otherwise.
*/
int LS_Empty(LinkedStack stack);

/**
@brief Adds an element to the top of the stack.

The function adds the data specified by \a el to the top of the stack.

@param stack the stack to add data to.
@param *el pointer to a initialized memory location containing the data to be
added at the top of the stack.
*/
void LS_Push(LinkedStack stack, void *el);

/**
@brief Removes an element from the top of the stack.

The function removes the element at the top of the stack. Note that the data in
that element is not freed, so that it can be further referenced.

@param stack the stack on which to perfom the operation
@see LS_Top()
*/
void LS_Pop(LinkedStack stack);

/**
@brief Retrieves the data in the element at the top of the stack.
The function returns the data in the element at the top of the stack but does
not alter in any way the \b structure of the stack. However the actual data can
be changed through the use of the \c void* pointer returned, which points to the
memory location containing the data.

@param stack the stack on which to perform the operation
@return if \a stack is \c NULL or empty, it returns \c NULL . Otherwise, it
returns a pointer to the memory location where the data in the element at the
top of the stack is stored.
*/
void *LS_Top(LinkedStack stack);

#endif /*LINKEDSTACK_H_*/
